﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
namespace MyPen
{
    public enum DrawType
    {
        Stop,
        Line,
        Rect,
        Circle,
        Sketch
    }
    public abstract class Shape
    {
        public abstract void Draw(Graphics g, DashStyle ds, double zoomRation);
        private int _penWidth = 10;


        public int PenWidth
        {
            get { return _penWidth; }
            set { _penWidth = value; }
        }
        private Color _penColor = Color.Red;

        public Color PenColor
        {
            get { return _penColor; }
            set { _penColor = value; }
        }
        //保存图元方法
        public abstract void Write(BinaryWriter bw);
        //读出图元方法
        public abstract void Read(BinaryReader br);


        
    }

    public class Line : Shape
    {
        private int _length;

        public int Length
        {
            get { return (int)Math.Sqrt(Math.Pow(P1.X - P2.X, 2) +
                                        Math.Pow(P1.Y - P2.Y, 2));}
        }

        private Point _p1;

        public Point P1
        {
            get { return _p1; }
            set { _p1 = value; }
        }
        private Point _p2;

        public Point P2
        {
            get { return _p2; }
            set { _p2 = value; }
        }

        public Line()
        {
 
        }

        public Line(Point p1, Point p2)
        {
            _p1 = p1;
            _p2 = p2;
        }

        public override void Draw(Graphics g, DashStyle ds, double zoomRation)
        {
            Pen pen = new Pen(PenColor, (int)(PenWidth * zoomRation));
            pen.DashStyle = ds;
            Point p1 = new Point((int)(_p1.X * zoomRation), (int)(_p1.Y * zoomRation));
            Point p2 = new Point((int)(_p2.X * zoomRation), (int)(_p2.Y * zoomRation));
            g.DrawLine(pen, p1, p2);
        }
        //保存图元方法
        public override void Write(BinaryWriter bw)
        {
            bw.Write(PenWidth);
            bw.Write(PenColor.ToArgb());
            bw.Write(_p1.X);
            bw.Write(_p1.Y);
            bw.Write(_p2.X);
            bw.Write(_p2.Y);
        }
        //读出图元方法
        public override void Read(BinaryReader br)
        {
            PenWidth = br.ReadInt32();
            PenColor = Color.FromArgb(br.ReadInt32());
            _p1.X = br.ReadInt32();
            _p1.Y = br.ReadInt32();
            _p2.X = br.ReadInt32();
            _p2.Y = br.ReadInt32();
        }
    }

    public class Rect : Shape 
    {
        private Point _p1;

        private double _wid;

        public double _Wid
        {
            get { return Math.Abs(_p1.X - _p2.X); }
        }

        private double _hei;

        public double _Hei
        {
            get { return Math.Abs(P1.Y - P2.Y); }
        }
        public Point P1
        {
            get { return _p1; }
            set { _p1 = value; }
        }
        private Point _p2;

        public Point P2
        {
            get { return _p2; }
            set { _p2 = value; }
        }

        public Rect()
        {
 
        }

        public Rect(Point p1, Point p2)
        {
            _p1 = p1;
            _p2 = p2;
        }

        public override void Draw(Graphics g, DashStyle ds, double zoomRation)
        {
            Pen pen = new Pen(PenColor, (int)(PenWidth * zoomRation));
            pen.DashStyle = ds;
            
            int leftPointX = (P1.X <= P2.X) ? (int)(P1.X * zoomRation) : (int)(P2.X * zoomRation);
            int leftPointY = (P1.Y <= P2.Y) ? (int)(P1.Y * zoomRation) : (int)(P2.Y * zoomRation);
            g.DrawRectangle(pen, leftPointX, leftPointY, Math.Abs(P1.X - P2.X), Math.Abs(P1.Y - P2.Y));
        }

        public override void Write(BinaryWriter bw)
        {
            bw.Write(PenWidth);
            bw.Write(PenColor.ToArgb());
            bw.Write(_p1.X);
            bw.Write(_p1.Y);
            bw.Write(_p2.X);
            bw.Write(_p2.Y);
        }

        public override void Read(BinaryReader br)
        {
            PenWidth = br.ReadInt32();
            PenColor = Color.FromArgb(br.ReadInt32());
            _p1.X = br.ReadInt32();
            _p1.Y = br.ReadInt32();
            _p2.X = br.ReadInt32();
            _p2.Y = br.ReadInt32();
        }
    }
     
    public class Circle : Shape
    {
        private Point _pCenter;


        public Point PCenter
        {
            get { return _pCenter; }
            set { _pCenter = value; }
        }
        private float _r;

        public float R
        {
            get { return _r; }
            set { _r = value; }
        }

        public Circle()
        {
 
        }

        public override void Draw(Graphics g, DashStyle ds, double zoomRation)
        {
            Pen pen = new Pen(PenColor, (int)(PenWidth * zoomRation));
            pen.DashStyle = ds;
            Point pCenter = new Point((int)(_pCenter.X * zoomRation), (int)(_pCenter.Y * zoomRation));
            float r = (float)(_r * zoomRation);
            g.DrawEllipse(pen, pCenter.X - r, pCenter.Y - r, 2 * r, 2 * _r);
        }

        public override void Write(BinaryWriter bw)
        {
            bw.Write(PenWidth);
            bw.Write(PenColor.ToArgb());
            bw.Write(_pCenter.X);
            bw.Write(_pCenter.Y);
            bw.Write(_r);
        }

        public override void Read(BinaryReader br)
        {
            PenWidth = br.ReadInt32();
            PenColor = Color.FromArgb(br.ReadInt32());
            _pCenter.X = br.ReadInt32();
            _pCenter.Y = br.ReadInt32();
            _r = br.ReadSingle();
        }


    }

    public class Sketch : Shape 
    {
        private List<Point> _pointList = new List<Point>();

        public List<Point> _PointList
        {
          get { return _pointList; }
          set { _pointList = value; }
        }
        public Sketch()
        {

        }

        public override void Draw(Graphics g, DashStyle ds, double zoomRation)
        {
            Pen pen = new Pen(PenColor, (int)(PenWidth * zoomRation));
            pen.DashStyle = ds;
            pen.StartCap = LineCap.Round;
            pen.EndCap = LineCap.Round;
            //只有当点数大于1时才绘制
            if (_PointList.Count > 1)
                for (int i = 0; i < _pointList.Count - 1; i++)
                {
                    Point p1 = new Point((int)(_pointList[i].X * zoomRation), (int)(_pointList[i].Y * zoomRation));
                    Point p2 = new Point((int)(_pointList[i + 1].X * zoomRation), (int)(_pointList[i + 1].Y * zoomRation));
                    g.DrawLine(pen, p1, p2);
                }
        }

        public override void Write(BinaryWriter bw)
        {
            bw.Write(PenWidth);
            bw.Write(PenColor.ToArgb());
            bw.Write(_pointList.Count);
            //依次保存每个点的X,Y坐标
            foreach(Point temp in _pointList)
            {
                bw.Write(temp.X);
                bw.Write(temp.Y);
            }
        }

        public override void Read(BinaryReader br)
        {
            PenWidth = br.ReadInt32();
            PenColor = Color.FromArgb(br.ReadInt32());
            //读出点的总数
            int pointCount = br.ReadInt32();
            for (int i = 0; i < pointCount - 1; i++)
            {
                int x = br.ReadInt32();
                int y = br.ReadInt32();
                Point temp = new Point(x, y);
                _pointList.Add(temp);
            }
        }

    }
    
}
